import CustomerRelationsManagement.CRMPrx;
import CustomerRelationsManagement.CRMPrxHelper;
import CustomerRelationsManagement.DBError;
import CustomerRelationsManagement.RecordNotFound;
import CustomerRelationsManagement.orderPrx;
import Ice.Current;
import Tracking.*;
import ws.tracking.*;
import java.util.*;


public class TrackingServiceImpl extends _TrackingServiceDisp {
	private CRMPrx crmproxy;
	
	@Override
	public RouteData getAllData(Current __current) {
		// TODO Auto-generated method stub
		System.out.println("Data has been retrieved");
		TrackingApp port = new TrackingAppService().getTrackingAppPort();
		List<Vehicle> routes = port.getAllCurrentRoutes();
		System.out.println(routes);
		return listToRouteData(routes);
	}

	@Override
	public void postNewRoutes(RouteData nrd, Current __current) {
		// TODO Auto-generated method stub
		System.out.println("Posting new routes");
		List<Vehicle> routes = routeDataToList(nrd);
		TrackingApp port = new TrackingAppService().getTrackingAppPort();
		port.setAllRoutes(routes);
	}

	public List<Vehicle> routeDataToList(RouteData routedata) {
		List<Vehicle> routes = new ArrayList<Vehicle>();
		Vehicle vehicle;
		Stop stop;
		Order order;
		SimpleDate simpledate;
		TruckData[] truckdatum = routedata.Trucks;
		TruckData truckdata;
		StopData[] stopdatum;
		StopData stopdata;
		StopActionData[] stopactiondatum;
		StopActionData stopactiondata;

		for (int i = 0; i < truckdatum.length; i++) {
			vehicle = new Vehicle();
			truckdata = truckdatum[i];
			vehicle.setCapacity(truckdata.capacity);
			vehicle.setId(Integer.parseInt(truckdata.id));
			stopdatum = truckdata.stops;
			for (int j = 0; j < stopdatum.length; j++) {
				stopdata = stopdatum[j];
				stop = new Stop();
				stop.setLocation(stopdata.location);
				stopactiondatum = stopdata.actions;
				for (int k = 0; k < stopactiondatum.length; k++) {
					stopactiondata = stopactiondatum[k];
					order = new Order();
					simpledate = new SimpleDate();
					simpledate.setDay((int) stopactiondata.Deadline.day);
					simpledate.setMonth((int) stopactiondata.Deadline.month);
					simpledate.setYear((int) stopactiondata.Deadline.year);
					order.setDeadline(simpledate);
					order.setDst(stopactiondata.dst);
					order.setId(stopactiondata.orderID);
					order.setSrc(stopactiondata.src);
					order.setWeight(stopactiondata.weight);
					if (stopactiondata.type == stopactiondata.type.DELIVERY) {
						stop.getDeliveries().add(order);
					} else {
						stop.getPickups().add(order);
					}
				}
				vehicle.getCurrentRoute().add(stop);
			}
			routes.add(vehicle);
		}
		return routes;
	}

	public RouteData listToRouteData(List<Vehicle> routes)
    {
        RouteData routedata = new RouteData();
        routedata.Trucks = new TruckData[routes.size()];
        TruckData truckdata;
        StopData stopdata;
        StopActionData stopactiondata;
        Vehicle vehicle;
        
        List<Stop> stops;
        List<Order> orders;
        Stop stop;
        Order order;
        for(int i = 0; i < routes.size(); i++)
        {
            vehicle = routes.get(i);
            truckdata = new TruckData();
            truckdata.capacity = (float)vehicle.getCapacity();
            truckdata.id = Integer.toString(vehicle.getId());
            stops = vehicle.getCurrentRoute();
            truckdata.stops = new StopData[stops.size()];
            for(int j=0; j<stops.size(); j++)
            {
                stop = stops.get(j);
                truckdata.stops[j] = new StopData();
                stopdata = truckdata.stops[j];
                stopdata.location = stop.getLocation();
                stopdata.actions = new StopActionData[stop.getDeliveries().size() + stop.getPickups().size()];
                
                orders = stop.getDeliveries();
                
                for(int k=0; k<orders.size(); k++)
                {
                    order = orders.get(k);
                    stopdata.actions[k] = new StopActionData();
                    stopactiondata = stopdata.actions[k];
                    //stopactiondata.customerID = stop.getDeliveries().get(k).getId();
                    stopactiondata.dst = order.getDst();
                    stopactiondata.orderID = order.getId();
                    stopactiondata.src = order.getSrc();
                    stopactiondata.type = StopAction.DELIVERY;
                    stopactiondata.weight = (float)order.getWeight();
                    stopactiondata.Deadline = new Tracking.datetime();
                    stopactiondata.Deadline.day = (byte)order.getDeadline().getDay();
                    stopactiondata.Deadline.month = (byte)order.getDeadline().getMonth();
                    stopactiondata.Deadline.year = (short)order.getDeadline().getYear();
                }
                
                orders = stop.getPickups();
                for(int k=0; k<orders.size(); k++)
                {
                    order = orders.get(k);
                    stopdata.actions[k + stop.getDeliveries().size()] = new StopActionData();
                    stopactiondata = stopdata.actions[k + stop.getDeliveries().size()];
                    //stopactiondata.customerID = stop.getDeliveries().get(k).getId();
                    stopactiondata.dst = order.getDst();
                    stopactiondata.orderID = order.getId();
                    stopactiondata.src = order.getSrc();
                    stopactiondata.type = StopAction.PICKUP;
                    stopactiondata.weight = (float)order.getWeight();
                    stopactiondata.Deadline = new Tracking.datetime();
                    stopactiondata.Deadline.day = (byte)order.getDeadline().getDay();
                    stopactiondata.Deadline.month = (byte)order.getDeadline().getMonth();
                    stopactiondata.Deadline.year = (short)order.getDeadline().getYear();
                }
            }
            routedata.Trucks[i] = truckdata;
        }
        return routedata;

    }
	
	public void intializeCRM(String crmServiceString) {
        //this.trackingServiceString = trackingServiceString;

        Ice.Communicator communicator = null;

        try {
            //
            // Boilerplate code for starting up the Ice runtime
            //
            Ice.Properties properties = Ice.Util.createProperties();
            properties.load("config_client");
            Ice.InitializationData id = new Ice.InitializationData();
            id.properties = properties;
            communicator = Ice.Util.initialize(id);

            String objectString = crmServiceString;
            Ice.ObjectPrx base = communicator.stringToProxy(objectString);

            crmproxy = CRMPrxHelper.checkedCast(base.ice_twoway().ice_timeout(-1).ice_secure(false));

            if (crmproxy == null) {
                System.err.println("invalid proxy");
                System.exit(1);
            }
        } catch (Ice.LocalException ex) {
            ex.printStackTrace();
            System.exit(1);
        }
	}
	
	public void postOnDelivery(int arg0)
	{
		 try {
			orderPrx op = crmproxy.LoadOrderById(arg0);
			op.setStatus(CustomerRelationsManagement.OrderStatus.DELIVERED);
			op.save();
		} catch (DBError e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RecordNotFound e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
